#ifndef __RT_PORT_H__
#define __RT_PORT_H__

#include <FreeRTOS.h>
#include <assert.h>
#include <semphr.h>
#include <stdbool.h>



#define ULOG_ASYNC_OUTPUT_THREAD_STACK (10*1024)
#define ULOG_ASYNC_OUTPUT_THREAD_PRIORITY tskIDLE_PRIORITY


#define rt_malloc       pvPortMalloc
#define rt_free         vPortFree

#define RT_ASSERT       configASSERT

#define rt_vsnprintf    vsnprintf
#define rt_snprintf     snprintf
#define rt_kprintf      printf
#define rt_kputs        puts

#define rt_thread_t         TaskHandle_t
#define rt_thread_delete    vTaskDelete

#define rt_ulog_mutex           SemaphoreHandle_t
#define rt_semaphoreStatic      StaticSemaphore_t
#define rt_semaphore            SemaphoreHandle_t
#define rt_sem_init(x)          xSemaphoreCreateBinaryStatic(x);
#define rt_sem_take(x, t)       xSemaphoreTake(x, t)
#define rt_sem_release(x)       xSemaphoreGive(x)

#define rt_mutex                SemaphoreHandle_t
#define rt_mutex_init()         xSemaphoreCreateMutex()
#define rt_mutex_detach(x)      vSemaphoreDelete(x)

#define RT_TICK_PER_SECOND      configTICK_RATE_HZ


#define RT_ALIGN_SIZE 8

#define rt_spinlock             SemaphoreHandle_t
#define rt_spinLockStatic       StaticSemaphore_t
#define rt_spin_lock_init(x)    xSemaphoreCreateMutexStatic(x)

#include "rtdevice.h"

rt_inline rt_base_t rt_spin_lock_irqsave(void)
{
    if (xPortIsInsideInterrupt()) {
        // 中断上下文保护
        return taskENTER_CRITICAL_FROM_ISR();
    }
    else
    {
        taskENTER_CRITICAL();
    }
    return 0;
}
rt_inline void rt_spin_unlock_irqrestore(rt_base_t level)
{
    if (xPortIsInsideInterrupt()) {
        // 中断上下文保护
        taskEXIT_CRITICAL_FROM_ISR(level);
    }
    else
    {
        taskEXIT_CRITICAL();
    }
}
rt_inline void rt_mutex_release(SemaphoreHandle_t xMutex)
{
    xSemaphoreGive(xMutex);
}
rt_inline void rt_mutex_take(SemaphoreHandle_t xMutex,int timeout)
{
    xSemaphoreTake(xMutex, timeout);
}
rt_inline bool rt_interrupt_get_nest()
{
    return (xPortIsInsideInterrupt() == pdFALSE);
}

#ifdef WIN32
rt_inline bool rt_scheduler_is_available()
{
    return xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED;
}

#endif


#endif